package vn.lumi.smarthome.provider;

import java.util.ArrayList;

import vn.lumi.smarthome.io.database.DatabaseHelper;
import vn.lumi.smarthome.io.database.TBL_Device;
import vn.lumi.smarthome.io.database.TBL_DeviceScene;
import vn.lumi.smarthome.io.database.TBL_DeviceState;
import vn.lumi.smarthome.io.database.TBL_Floor;
import vn.lumi.smarthome.io.database.TBL_Room;
import vn.lumi.smarthome.io.database.TBL_Scene;
import vn.lumi.smarthome.io.model.Device;
import vn.lumi.smarthome.io.model.DeviceState;
import vn.lumi.smarthome.io.model.Floor;
import vn.lumi.smarthome.io.model.Room;
import vn.lumi.smarthome.ulti.LogUltis;
import android.annotation.SuppressLint;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.Build;
import android.provider.ContactsContract.Contacts.Data;

public class SmartHomeProvider extends ContentProvider{
	private static final String TAG="SmartHomeProvider";
	
	public static final String AUTHORITY="vn.lumi.smarthome.provider.SmartHomeProvider";
	private static UriMatcher sUriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
	
	private static final int OPT_FLOOR=1;
	private static final int OPT_ROOM=OPT_FLOOR+1; 
	private static final int OPT_DEVICES=OPT_ROOM+1;
	private static final int OPT_DEVICE_STATE=OPT_DEVICES+1;
	private static final int OPT_SCENE=OPT_DEVICE_STATE+1;
	private static final int OPT_DEVICE_SCENE=OPT_SCENE+1;
	private static final int OPT_DEVICE_ID=OPT_DEVICE_SCENE+1;
		
	static
	{
		sUriMatcher.addURI(AUTHORITY, TBL_Floor.FLOOR, OPT_FLOOR);
		sUriMatcher.addURI(AUTHORITY, TBL_Room.ROOM, OPT_ROOM);
		sUriMatcher.addURI(AUTHORITY, TBL_Device.DEVICES, OPT_DEVICES);
		sUriMatcher.addURI(AUTHORITY, TBL_Device.DEVICES+"/*", OPT_DEVICE_STATE);
		sUriMatcher.addURI(AUTHORITY, TBL_Device.DEVICES_TYPE, OPT_DEVICE_ID);
		sUriMatcher.addURI(AUTHORITY, TBL_Scene.SCENE, OPT_SCENE);
		sUriMatcher.addURI(AUTHORITY, TBL_DeviceScene.DEVICE_SCENE, OPT_DEVICE_SCENE);
	}
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		return 0;
	}

	@Override
	public String getType(Uri uri) {
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		SQLiteDatabase database=DatabaseHelper.getInstanceDatabaseDream(getContext());
		long row=-1;
		int match=sUriMatcher.match(uri);
		switch (match) {
		case OPT_SCENE:
			row=database.insert(DatabaseHelper.DB_TBL_SCENE, null, values);
			break;
		case OPT_DEVICE_STATE:
			row=database.insert(DatabaseHelper.DB_TBL_DEVICE_STATE, null, values);
			break;
		case OPT_DEVICE_SCENE:
			row=database.insert(DatabaseHelper.DB_TBL_DEVICE_SCENE, null, values);
			break;

		default:
			break;
		}
		return Uri.withAppendedPath(uri, row+"");
	}

	@Override
	public boolean onCreate() {
		return false;
	}

	@SuppressLint("NewApi")
	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		int match=sUriMatcher.match(uri);
		SQLiteDatabase sqLiteDatabase=DatabaseHelper.getInstanceDatabaseDream(getContext());
		Cursor cursor=null;
		switch (match) {
		case OPT_FLOOR:
			LogUltis.i(TAG, "Query floor table");
			cursor=sqLiteDatabase.query(DatabaseHelper.DB_TBL_FLOOR, projection, null,selectionArgs,null,sortOrder,null);
			break;
		case OPT_ROOM:
			LogUltis.i(TAG, "Query room table");
			cursor=sqLiteDatabase.query(DatabaseHelper.DB_TBL_ROOM, projection, selection,selectionArgs,null,null,sortOrder);
			break;
		case OPT_DEVICES:
			String device_id=DatabaseHelper.DB_TBL_DEVICE+"."+TBL_Device._ID;
			String device_type=DatabaseHelper.DB_TBL_DEVICE+"."+TBL_Device.TYPE_ID;
			String room_id=DatabaseHelper.DB_TBL_DEVICE+"."+TBL_Device.ROOM_ID;
			String device_name=DatabaseHelper.DB_TBL_DEVICE+"."+TBL_Device.NAME;
			String device_stateid=DatabaseHelper.DB_TBL_DEVICE+"."+TBL_Device.STATE_ID;
			String is_control=DatabaseHelper.DB_TBL_DEVICE+"."+TBL_Device.IS_CONTROL;
			
			String state_id=DatabaseHelper.DB_TBL_DEVICE_STATE+"."+TBL_DeviceState._ID;
			String value=DatabaseHelper.DB_TBL_DEVICE_STATE+"."+TBL_DeviceState.VALUE;
			String RGB=DatabaseHelper.DB_TBL_DEVICE_STATE+"."+TBL_DeviceState.RGB;
			
			String[] projections=new String[]{device_id,device_type,room_id,device_name,device_stateid,is_control,value,RGB};
			
			String stringInner=DatabaseHelper.DB_TBL_DEVICE+" INNER JOIN "+DatabaseHelper.DB_TBL_DEVICE_STATE+" ON ("+device_stateid+"="+state_id+")";
			
			SQLiteQueryBuilder sqLiteQueryBuilder=new SQLiteQueryBuilder();
			sqLiteQueryBuilder.setTables(stringInner);
			
			if(Build.VERSION.SDK_INT<11){
				@SuppressWarnings("deprecation")
				String query=sqLiteQueryBuilder.buildQuery(projections, selection, selectionArgs,null, null, sortOrder, null);
				LogUltis.i(TAG, "SQL get devices (API<11)=["+query+"]");
				cursor=sqLiteDatabase.rawQuery(query, selectionArgs);
			}else{
				String query=sqLiteQueryBuilder.buildQuery(projections, selection, null, null, sortOrder, null);
				LogUltis.i(TAG, "SQL get devices (API>=11)=["+query+"]");
				cursor=sqLiteDatabase.rawQuery(query, selectionArgs);
			}
			break;
		case OPT_DEVICE_SCENE:
			LogUltis.i(TAG, "Query device Scene");
			String[] pros=new String[]{DatabaseHelper.DB_TBL_DEVICE_SCENE+"."+TBL_DeviceScene._ID,TBL_DeviceScene.SCENE_ID,TBL_DeviceScene.DEVICE_ID,TBL_DeviceScene.STATE_ID,TBL_DeviceState.VALUE,TBL_DeviceState.RGB,TBL_Device.TYPE_ID};
			String inner=DatabaseHelper.DB_TBL_DEVICE_SCENE+" INNER JOIN "+DatabaseHelper.DB_TBL_DEVICE_STATE +" ON ("+TBL_DeviceScene.STATE_ID+"="+DatabaseHelper.DB_TBL_DEVICE_STATE+"."+TBL_DeviceState._ID+"), "+DatabaseHelper.DB_TBL_DEVICE_SCENE+" INNER JOIN "+DatabaseHelper.DB_TBL_DEVICE+" ON ("+TBL_DeviceScene.DEVICE_ID+"="+TBL_Device._ID+")";
			
			SQLiteQueryBuilder builder=new SQLiteQueryBuilder();
			builder.setTables(inner);
			
			if(Build.VERSION.SDK_INT<11){
				@SuppressWarnings("deprecation")
				String query=builder.buildQuery(pros, selection, selectionArgs,null, null, sortOrder, null);
				LogUltis.i(TAG, "SQL get device_scene (API<11)=["+query+"]");
				cursor=sqLiteDatabase.rawQuery(query, selectionArgs);
			}else{
				String query=builder.buildQuery(pros, selection, null, null, sortOrder, null);
				LogUltis.i(TAG, "SQL get device_scene (API>=11)=["+query+"]");
				cursor=sqLiteDatabase.rawQuery(query, selectionArgs);
			}
			
			break;
		case OPT_SCENE:
			cursor=sqLiteDatabase.query(DatabaseHelper.DB_TBL_SCENE,projection,selection,selectionArgs,null,null,null);
			break;
		case OPT_DEVICE_ID:
			cursor=sqLiteDatabase.query(DatabaseHelper.DB_TBL_DEVICE, projection, selection, selectionArgs, null, null, null);
			break;
		case OPT_DEVICE_STATE:
			inner=DatabaseHelper.DB_TBL_DEVICE+" INNER JOIN "+DatabaseHelper.DB_TBL_DEVICE_STATE+" ON("+TBL_Device.STATE_ID+"="+TBL_DeviceState._ID+")";
			SQLiteQueryBuilder builder2=new SQLiteQueryBuilder();
			builder2.setTables(inner);
			String[] pro=new String[]{TBL_DeviceState._ID,TBL_DeviceState.VALUE,TBL_DeviceState.RGB};
			String s=builder2.buildQuery(pro, selection, selectionArgs, null, null, null, null);
			cursor=sqLiteDatabase.rawQuery(s,selectionArgs);
			
			break;
		default:
			break;
		}
		if(cursor!=null){
			LogUltis.i(TAG, "cursor ! null, num rows="+cursor.getCount());
			cursor.setNotificationUri(getContext().getContentResolver(), uri);
		}
		return cursor;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
		SQLiteDatabase sqLiteDatabase=DatabaseHelper.getInstanceDatabaseDream(getContext());
		int match=sUriMatcher.match(uri);
		int effect=0;
		switch (match) {
		case OPT_DEVICES:
			effect=sqLiteDatabase.update(DatabaseHelper.DB_TBL_DEVICE, values, selection, selectionArgs);
			break;
		case OPT_DEVICE_STATE:
			LogUltis.i(TAG, "update device_state");
			effect=sqLiteDatabase.update(DatabaseHelper.DB_TBL_DEVICE_STATE, values, selection, selectionArgs);
			break;

		default:
			break;
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return effect;
	}
	/**
	 * Insert Config receive from HC to Database
	 * @param context
	 * @param floors
	 */
	public static void insertDataFromHCToDB(Context context,ArrayList<Floor> floors){
		for (int i = 0; i < floors.size(); i++) {
			Floor floor=floors.get(i);
			//insert floor
			ContentValues contentValues=new ContentValues();
			contentValues.put(TBL_Floor._ID, floor.getId());
			contentValues.put(TBL_Floor.NAME, floor.getName());
			context.getContentResolver().insert(TBL_Floor.CONTENT_URI_FLOOR, contentValues);
			contentValues.clear();
			//insert floor//
			
			Room[] rooms=floor.getRooms();
			for (int j = 0; j < rooms.length; j++) {
				Room room=rooms[j];
				//insert room
				contentValues.put(TBL_Room._ID, room.getId());
				contentValues.put(TBL_Room.FLOOR_ID, floor.getId());
				contentValues.put(TBL_Room.NAME, room.getName());
				context.getContentResolver().insert(TBL_Room.CONTENT_URI_ROOM, contentValues);
				contentValues.clear();
				//insert room//
				
				Device[] devices=room.getDevices();
				for (int k = 0; k < devices.length; k++) {
					DeviceState deviceState=devices[k].getDeviceState();
					//insert DeviceState
					contentValues.put(TBL_DeviceState.VALUE, deviceState.getValue());
					contentValues.put(TBL_DeviceState.RGB, deviceState.getRGB());
					contentValues.put(TBL_DeviceState.BLIND_STATE, deviceState.getBlind_state());
					Uri uri=context.getContentResolver().insert(TBL_DeviceState.CONTENT_URI_DEVICE_STATE, contentValues);
					int device_state_id=Integer.parseInt(uri.getLastPathSegment());
					contentValues.clear();
					//insert DeviceState//
					
					//insert Device
					Device device=devices[k];
					contentValues.put(TBL_Device._ID, device.getId());
					contentValues.put(TBL_Device.NAME, device.getName());
					contentValues.put(TBL_Device.ROOM_ID, room.getId());
					contentValues.put(TBL_Device.STATE_ID, device_state_id);
					contentValues.put(TBL_Device.TYPE_ID, device.getType_id());
					contentValues.put(TBL_Device.IS_CONTROL,0);
					context.getContentResolver().insert(TBL_Device.CONTENT_URI_DEVICES, contentValues);
					contentValues.clear();
					//insert Device//
				}
			}
		}
	}
	
	public static int getDeviceType(Context context,int deviceID){
		int deviceType=-1;
		
		Uri uri=TBL_Device.CONTENT_URI_DEVICE_TYPE;
		String[] projection=new String[]{TBL_Device.TYPE_ID};
		String selection=TBL_Device._ID+"=?";
		String[] selectionArgs=new String[]{deviceID+""};
				
		Cursor cursor=context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
		if(cursor!=null){
			if(cursor.moveToFirst())
				deviceType=cursor.getInt(cursor.getColumnIndex(TBL_Device.TYPE_ID));
		}
		return deviceType;
	}
	
	public static DeviceState getDeviceStateByDeviceID(Context context,int deviceID){
		DeviceState deviceState=new DeviceState();
		Uri uri = null;
		String selection=TBL_Device._ID+"=?";
		String[] selectionArgs=new String[]{deviceID+""};
		Cursor cursor=context.getContentResolver().query(uri, null, selection, selectionArgs, null);
		if(cursor!=null){
			if(cursor.moveToFirst()){
				deviceState.setRGB(cursor.getInt(cursor.getColumnIndex(TBL_DeviceState.RGB)));
				deviceState.setId(cursor.getInt(cursor.getColumnIndex(TBL_DeviceState._ID)));
				deviceState.setValue(cursor.getInt(cursor.getColumnIndex(TBL_DeviceState.VALUE)));
			}
		}
		return deviceState;
	}
	

}
